home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / sec / part01 next >
Encoding:
Text File  |  1990-10-14  |  10.8 KB  |  425 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: nsayer@uop.uop.edu
  3. organization: University of the Pacific, Stockton, CA [138.9.200.1]
  4. subject: v15i048: Root-shell giver -- new and improved "su"
  5. from: mrapple@quack.sac.ca.us (Nick Sayer)
  6. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7.  
  8. Posting-number: Volume 15, Issue 48
  9. Submitted-by: mrapple@quack.sac.ca.us (Nick Sayer)
  10. Archive-name: sec/part01
  11.  
  12. [Uses syslog and is otherwise BSD-specific; however, it should not be too
  13. difficult to convert to System V.
  14.  
  15. I must admit that giving each user who is permitted to use root a password
  16. that only works for that user is an improvement over the standard "su" model,
  17. and certainly over a program that was in use on ncoast some years ago.  But
  18. remember that giving *anyone* other than the system administrator the ability
  19. to access root is a potential security hole; as always, consider carefully
  20. before allowing someone root access.  ++bsa]
  21.  
  22. I'm not quite sure what to call this, but I call it "sec." Anyway,
  23. I've had a couple requests for it, so I thought I'd pass it along.
  24.  
  25. #!/bin/sh
  26. # This is a shell archive (produced by shar 3.49)
  27. # To extract the files from this archive, save it to a file, remove
  28. # everything above the "!/bin/sh" line above, and type "sh file_name".
  29. #
  30. # made 10/08/1990 19:39 UTC by nsayer@uop
  31. # Source directory /files/users/staff-uop/nsayer/sec
  32. #
  33. # existing files will NOT be overwritten unless -c is specified
  34. #
  35. #                                                                          
  36. #                                                                          
  37. #
  38. # This shar contains:
  39. # length  mode       name
  40. # ------ ---------- ------------------------------------------
  41. #   1315 -rw-r--r-- sec.c
  42. #   1672 -rw-r--r-- secpw.c
  43. #    737 -rw-r--r-- Makefile
  44. #   1803 -rw-r--r-- README
  45. #    796 -rw-r--r-- config.h
  46. #
  47. if test -r _shar_seq_.tmp; then
  48.     echo 'Must unpack archives in sequence!'
  49.     echo Please unpack part `cat _shar_seq_.tmp` next
  50.     exit 1
  51. fi
  52. # ============= sec.c ==============
  53. if test -f 'sec.c' -a X"$1" != X"-c"; then
  54.     echo 'x - skipping sec.c (File already exists)'
  55.     rm -f _shar_wnt_.tmp
  56. else
  57. > _shar_wnt_.tmp
  58. echo 'x - extracting sec.c (Text)'
  59. sed 's/^X//' << 'SHAR_EOF' > 'sec.c' &&
  60. /*
  61. X *
  62. X * sec.c
  63. X *
  64. X * Grudgingly give out root shells to authorized users.
  65. X *
  66. X * Usage: sec
  67. X *
  68. X */
  69. X
  70. #include <stdio.h>
  71. #include <syslog.h>
  72. #include <strings.h>
  73. #include "config.h"
  74. X
  75. int getline(file,s)
  76. FILE *file;
  77. char *s;
  78. {
  79. X  while (((*s=getc(file))!=EOF) && (*s!='\n')) s++;
  80. X  if ((*s)==EOF) return 0;
  81. X  *s=0;
  82. X  return 1;
  83. }
  84. X
  85. extern char *crypt();
  86. X
  87. char ckpw(b)
  88. char *b;
  89. {
  90. X  char *a,*encr,input[10];
  91. X  int f;
  92. X
  93. X  if (!strlen(b))
  94. X  {
  95. X    printf("Null PW. Please use 'secpw' and add one.\n");
  96. X    return 1;
  97. X  }
  98. X  strcpy(input,getpass("Password:"));
  99. X  encr=crypt(input,b);
  100. X  return(!strcmp(encr,b));
  101. }
  102. X
  103. main()
  104. {
  105. X  FILE* f;
  106. X  char str[80],ok=0;
  107. X
  108. X  f=fopen(FILENAME,"r");
  109. X  if (f!=NULL)
  110. X  {
  111. X    while(getline(f,str))
  112. X    {
  113. X      char b[16],*c;
  114. X      c=index(str,':');
  115. X      if (c==NULL) continue;
  116. X      strcpy(b,c+1);
  117. X      *c='\0';
  118. X      if (!strcmp(str,getlogin()))
  119. X        if (ckpw(b))
  120. X          ok=1;
  121. X    }
  122. X    fclose(f);
  123. X  }
  124. X  else
  125. X  {
  126. X    printf("Error reading file.\n");
  127. X    exit(1);
  128. X  }
  129. X
  130. X  openlog("sec",0,LOG_FACILITY);
  131. X
  132. X  if (ok)
  133. X  {
  134. X    syslog(LOG_OK_PRI,"security access: %s",getlogin());
  135. X    seteuid(0);
  136. X    setegid(0);
  137. X    setuid(0);
  138. X    setgid(0);
  139. X    execl("/bin/csh"," SEC",(char*)0);
  140. X  }
  141. X  else
  142. X  {
  143. X    syslog(LOG_FAIL_PRI,"security access DENIED: %s",getlogin());
  144. X    printf("Not Authorized.\n");
  145. X  }
  146. }
  147. SHAR_EOF
  148. chmod 0644 sec.c ||
  149. echo 'restore of sec.c failed'
  150. Wc_c="`wc -c < 'sec.c'`"
  151. test 1315 -eq "$Wc_c" ||
  152.     echo 'sec.c: original size 1315, current size' "$Wc_c"
  153. rm -f _shar_wnt_.tmp
  154. fi
  155. # ============= secpw.c ==============
  156. if test -f 'secpw.c' -a X"$1" != X"-c"; then
  157.     echo 'x - skipping secpw.c (File already exists)'
  158.     rm -f _shar_wnt_.tmp
  159. else
  160. > _shar_wnt_.tmp
  161. echo 'x - extracting secpw.c (Text)'
  162. sed 's/^X//' << 'SHAR_EOF' > 'secpw.c' &&
  163. /*
  164. X *
  165. X * secpw.c
  166. X *
  167. X * Change passwords for the sec password file
  168. X *
  169. X * Usage: secpw [username]
  170. X *
  171. X * It may seem odd that users are allowed to change other people's
  172. X * passwords, and change their own without supplying the old password,
  173. X * but whoever runs this must already have a uid of root, so it
  174. X * really doesn't matter.
  175. X *
  176. X */
  177. X
  178. #include <stdio.h>
  179. #include <strings.h>
  180. #include <sys/file.h>
  181. #include "config.h"
  182. X
  183. extern long random();
  184. extern char *getlogin();
  185. extern long time();
  186. X
  187. char charset[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
  188. X
  189. char getline(file,s)
  190. FILE *file;
  191. char *s;
  192. {
  193. X  while(((*s=getc(file))!=EOF) && (*s!='\n')) s++;
  194. X  if ((*s)==EOF) return 1;
  195. X  *s=0;
  196. X  return 0;
  197. }
  198. X
  199. main(argc,argv)
  200. int argc;
  201. char **argv;
  202. {
  203. X
  204. X  char key[9],salt[3],line[80],line2[80],*who,ok=0;
  205. X  FILE *f1,*f2;
  206. X
  207. X  if (setuid(0))
  208. X  {
  209. X    printf("Must be root.\n");
  210. X    exit(1);
  211. X  }
  212. X
  213. X  who=getlogin();
  214. X  if (argc>1)
  215. X    who=*(argv+1);
  216. X
  217. X  strcpy(key,getpass("New Password:"));
  218. X  if (strcmp(key,getpass("Again:")))
  219. X  {
  220. X    printf("No Match.\n");
  221. X    exit(1);
  222. X  }
  223. X
  224. X  srandom((int) time(0L));
  225. X  salt[0]=charset[random()%strlen(charset)];
  226. X  salt[1]=charset[random()%strlen(charset)];
  227. X  strcpy(line,who);
  228. X  strcat(line,":");
  229. X  strcat(line,crypt(key,salt));
  230. X
  231. X  umask(0377);
  232. X  f1=fopen(FILENAME,"r");
  233. X  f2=fopen(TEMPNAME,"w");
  234. X  flock(fileno(f2),LOCK_EX);
  235. X  while(!getline(f1,line2))
  236. X    if (strncmp(line2,who,strlen(who)))
  237. X      fprintf(f2,"%s\n",line2);
  238. X    else
  239. X    {
  240. X      fprintf(f2,"%s\n",line);
  241. X      ok++;
  242. X    }
  243. X  fclose(f1);
  244. X  fclose(f2);
  245. X  rename(TEMPNAME,FILENAME);
  246. X
  247. X  if (!ok)
  248. X  {
  249. X    printf("Cannot change: User not authorized.\n");
  250. X    exit(1);
  251. X  }
  252. X  
  253. }
  254. SHAR_EOF
  255. chmod 0644 secpw.c ||
  256. echo 'restore of secpw.c failed'
  257. Wc_c="`wc -c < 'secpw.c'`"
  258. test 1672 -eq "$Wc_c" ||
  259.     echo 'secpw.c: original size 1672, current size' "$Wc_c"
  260. rm -f _shar_wnt_.tmp
  261. fi
  262. # ============= Makefile ==============
  263. if test -f 'Makefile' -a X"$1" != X"-c"; then
  264.     echo 'x - skipping Makefile (File already exists)'
  265.     rm -f _shar_wnt_.tmp
  266. else
  267. > _shar_wnt_.tmp
  268. echo 'x - extracting Makefile (Text)'
  269. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  270. #
  271. # Makefile for sec
  272. #
  273. # To install: Patch config.h to change the location of the security filename.
  274. # Then make, su, and make install.
  275. # Then create the security file. See README
  276. #
  277. X
  278. #CC=/bin/cc
  279. X
  280. # for SunOS 4.0 and above, static binding is recommended. If sharing
  281. # a library by NFS, it may become disconnected, rendering sec unavailable.
  282. X
  283. CFLAGS= -O -Bstatic
  284. X
  285. GROUP=staff
  286. INSTALLDIR=/etc
  287. X
  288. all:sec secpw
  289. X
  290. sec:sec.o
  291. X    $(CC) $(CFLAGS) -o sec sec.o
  292. X    strip sec
  293. X
  294. secpw:secpw.o
  295. X    $(CC) $(CFLAGS) -o secpw secpw.o
  296. X    strip secpw
  297. X
  298. sec.o:sec.c config.h
  299. X
  300. secpw.o:secpw.c config.h
  301. X
  302. install:sec secpw
  303. X    mv sec secpw $(INSTALLDIR)
  304. X    cd $(INSTALLDIR)
  305. X    chmod 4710 sec
  306. X    chmod 710 secpw
  307. X    chown root sec secpw
  308. X    chgrp $(GROUP) sec secpw
  309. X
  310. clean:
  311. X    rm -f *.o core
  312. SHAR_EOF
  313. chmod 0644 Makefile ||
  314. echo 'restore of Makefile failed'
  315. Wc_c="`wc -c < 'Makefile'`"
  316. test 737 -eq "$Wc_c" ||
  317.     echo 'Makefile: original size 737, current size' "$Wc_c"
  318. rm -f _shar_wnt_.tmp
  319. fi
  320. # ============= README ==============
  321. if test -f 'README' -a X"$1" != X"-c"; then
  322.     echo 'x - skipping README (File already exists)'
  323.     rm -f _shar_wnt_.tmp
  324. else
  325. > _shar_wnt_.tmp
  326. echo 'x - extracting README (Text)'
  327. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  328. sec is a password protected means of allowing specified users to
  329. obtain a root shell without giving them the system's root password.
  330. It is similar in this regard to su, except that each user has his
  331. own password, which can be changed at any time. These passwords and
  332. authorized users are stored in a security file hidden cleverly
  333. somewhere on a mounted file system (at your descretion).
  334. X
  335. This is MARGINALLY safer than releasing the root password, but
  336. NOT MUCH. REMEMBER: When someone IS root they can do anything.
  337. This program, used improperly can be DANGEROUS! By itself, this
  338. source is not, since it must be run suid for it to work.
  339. X
  340. sec will log to syslog successful and unsuccessful attempts to
  341. get a root shell. If you don't have syslog, a phoney syslog
  342. routine is provided to log to a file.
  343. X
  344. The security file itself is owned by root and chmod'd to u+r (0400).
  345. The format is one user per line, the username, followed by a colon,
  346. followed by an optional crypted password. To add a user, simply add
  347. the user to the file, with the ":" as the last character on the line.
  348. Then either use secpw to set the password, or remind the user to do
  349. this the first time he uses sec (sec will warn when a user has a null
  350. PW, but will allow root access anyway).
  351. X
  352. secpw may be used to change someone else's security password, in case
  353. that user is compromised. secpw tries to setuid itself to root as a
  354. test to see if it is being run by root. Therefore you must NOT suid
  355. secpw. secpw will not run if it can't setuid(0), so to change your sec
  356. password, you first have to get into sec (or root), presumably using
  357. your old password.
  358. X
  359. As further protection, it is suggested that sec authorized users be placed
  360. into a separate "operator" or "sec" group, and that only this group be
  361. allowed to even run sec (chmod o-rwx).
  362. SHAR_EOF
  363. chmod 0644 README ||
  364. echo 'restore of README failed'
  365. Wc_c="`wc -c < 'README'`"
  366. test 1803 -eq "$Wc_c" ||
  367.     echo 'README: original size 1803, current size' "$Wc_c"
  368. rm -f _shar_wnt_.tmp
  369. fi
  370. # ============= config.h ==============
  371. if test -f 'config.h' -a X"$1" != X"-c"; then
  372.     echo 'x - skipping config.h (File already exists)'
  373.     rm -f _shar_wnt_.tmp
  374. else
  375. > _shar_wnt_.tmp
  376. echo 'x - extracting config.h (Text)'
  377. sed 's/^X//' << 'SHAR_EOF' > 'config.h' &&
  378. /*
  379. X *
  380. X * config.h for sec/secpw
  381. X *
  382. X */
  383. X
  384. /*
  385. X
  386. The first three definitions are for syslog. The first is the logging
  387. facility code to use. LOG_FAIL_PRI is the priority to use when logging
  388. a failure in authorization message. I.e. mistyped password, unauthorized
  389. user, etc. LOG_OK_PRI is the priority to use when logging a successful
  390. attempt.
  391. X
  392. */
  393. X
  394. #define LOG_FACILITY LOG_AUTH
  395. #define LOG_FAIL_PRI LOG_WARNING
  396. #define LOG_OK_PRI LOG_NOTICE
  397. X
  398. /*
  399. X
  400. The next definition is the location of the security file, and the temporary
  401. file for secpw to use. the temp file MUST be on the same file system as
  402. the real file. rename() is used to move the temp to the real one when
  403. the change is done. Just like vipw.
  404. X
  405. */
  406. X
  407. #define FILENAME "/usr/adm/security"
  408. #define TEMPNAME "/usr/adm/security.tmp"
  409. #include <stdio.h>
  410. SHAR_EOF
  411. chmod 0644 config.h ||
  412. echo 'restore of config.h failed'
  413. Wc_c="`wc -c < 'config.h'`"
  414. test 796 -eq "$Wc_c" ||
  415.     echo 'config.h: original size 796, current size' "$Wc_c"
  416. rm -f _shar_wnt_.tmp
  417. fi
  418. exit 0
  419. -- 
  420. Nick Sayer               |  Disclaimer:
  421. N6QQQ                    |    "Just because you're reading my post doesn't
  422. mrapple@quack.sac.ca.us  |     mean we're gonna take long showers together."
  423. 209-952-5347 (Telebit)   |                      -- Gunnery Sgt. Thomas Highway
  424.  
  425.